package com.naiterui.ehp.bs.doctor.dao.mongo;

import java.util.Collection;
import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.BasicDBObject;
import com.naiterui.common.repository.page.Page;

/**
 * 基于Spring MongoTemplate的MongoDB操作封装
 * <P>File name : MongoBaseDao.java </P>
 * <P>Author : zhouyanxin </P>
 * <P>Date : 2015年6月28日 </P>
 */
public abstract class MongoBaseDao {

    /**
     * mongodb template
     */
    protected abstract MongoTemplate getMongoTemplate();

    /**
     * 分页查询
     * MongoBaseDao.find()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-10-11 </P>
     *
     * @param query
     * @param entityClass
     * @param collectionName
     * @param page
     * @param num
     *
     * @return
     */
    protected <T> List<T> find(Query query, Class<T> entityClass, String collectionName) {
        return this.getMongoTemplate().find(query, entityClass, collectionName);
    }

    /**
     * 查询总数量
     * MongoBaseDao.queryCount()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-10-11 </P>
     *
     * @param query
     * @param collectionName
     *
     * @return
     */
    protected long queryCount(Query query, String collectionName) {
        return this.getMongoTemplate().count(query, collectionName);
    }

    /**
     * 保存
     * MongoBaseDao.save()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-10-20 </P>
     *
     * @param save
     * @param collectionName
     *
     * @return
     */
    protected <T> void save(T t, String collectionName) {
        this.getMongoTemplate().save(t, collectionName);
    }

    /**
     * 查找全部
     * MongoBaseDao.findAll()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-10-20 </P>
     *
     * @param save
     * @param collectionName
     *
     * @return
     */
    protected <T> List<T> findAll(Class<T> entityClass, String collectionName) {
        return this.getMongoTemplate().findAll(entityClass, collectionName);
    }

    /**
     * 保存对象
     * MongoBaseDao.update()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-10-20 </P>
     *
     * @param update
     * @param collectionName
     *
     * @return
     */
    protected <T> void update(T o, T n) {
        this.getMongoTemplate().remove(o);
        this.getMongoTemplate().save(n);
    }

    /**
     * 更新对象
     * MongoBaseDao.update()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-12-20 </P>
     *
     * @param update
     *
     * @return
     */
    protected <T> void update(Class<T> entityClass, String collectionName, Query query, Update update) {
        this.getMongoTemplate().updateFirst(query, update, entityClass, collectionName);
    }

    /**
     * 删除对象
     * MongoBaseDao.remove()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-12-01 </P>
     *
     * @param t
     * @param collectionName
     *
     * @return
     */
    protected <T> void remove(T t, String collectionName) {
        this.getMongoTemplate().remove(t, collectionName);
    }

    /**
     * 删除对象
     * MongoBaseDao.remove()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2014-12-01 </P>
     *
     * @param t
     * @param collectionName
     *
     * @return
     */
    protected <T> void remove(Query query, String collectionName) {
        this.getMongoTemplate().remove(query, collectionName);
    }

    /***
     * 批量插入
     * MongoBaseDao.saveBatch()
     * @Author chenlin
     * @Date 2016年3月30日
     * @since 1.0.0
     * @param batchToSave
     * @param collectionName
     */
    protected <T> void saveBatch(Collection<T> batchToSave, String collectionName) {
        this.getMongoTemplate().insert(batchToSave, collectionName);
    }

    /**
     * 分页查询 MongoBaseDao.queryByPage()<BR> <P>Author : zhouyanxin </P> <P>Date :
     * 2015年7月4日 </P>
     *
     * @param collectioinName
     * @param clazz
     * @param criteria
     * @param page
     * @param num
     * @param orderBy
     * @param orderByItem
     *
     * @return
     */
    protected <T> List<T> queryByPage(String collectionName, Class<T> entityClass, Criteria criteria, int pageNo, int pageSize, String orderBy,
                                      String orderByItem) {
        int skipNum = (pageNo - 1) * pageSize;
        Query query = null;
        if (Page.ASC.equals(orderBy)) {
            query = Query.query(criteria).skip(skipNum).limit(pageSize).with(Sort.by(new Sort.Order(Direction.ASC, orderByItem)));
        } else {
            query = Query.query(criteria).skip(skipNum).limit(pageSize).with(Sort.by(new Sort.Order(Direction.DESC, orderByItem)));
        }

        return this.find(query, entityClass, collectionName);
    }

    /**
     * 查询出一个
     *
     * @param query
     * @param collectionName
     *
     * @return
     *
     * @Author He Qiang
     * @Date 2016年8月4日
     * @since 1.0.0
     */
    protected BasicDBObject findOne(Query query, String collectionName) {
        return this.getMongoTemplate().findOne(query, BasicDBObject.class, collectionName);
    }
}
